package admin

import (
	"ecms/models"
	"ecms/utils/converter"
	"ecms/utils/reflects"
	"ecms/utils/repository"
	"ecms/utils/response"
	"ecms/utils/validator"
	"github.com/gin-gonic/gin"
)

type ContentFieldTypeController struct{}

// Index 内容字段类型列表
func (c *ContentFieldTypeController) Index(ctx *gin.Context) {
	reqData := make(map[string]string)
	rules := validator.NewRules(
		validator.NewRule("status", "状态", true, validator.TypeStatus),
		validator.NewRule("page", "分页", true, validator.TypeNumberNoneZero),
		validator.NewRule("page_size", "分页大小", true, validator.TypeNumberNoneZero),
		validator.NewRule("keyword", "搜索词", false, validator.TypeNoEmpty),
	)
	if !validator.ShouldBindMapFromPostForm(ctx, &reqData, rules...) {
		return
	}

	lists := make([]models.ContentFieldType, 0)
	var total int64 = 0
	repo := repository.New(&models.ContentFieldType{})

	query := "status = ? AND is_deleted = 0"
	args := []interface{}{reqData["status"]}
	if reqData["keyword"] != "" {
		repo.BuildSearchQuery(&query, []string{"name", "description", "db_type"}, reqData["keyword"], &args)
	}

	if !repo.Pagination(&repository.PaginationQuery{
		Out:      &lists,
		Page:     converter.Str2Int(reqData["page"]),
		PageSize: converter.Str2Int(reqData["page_size"]),
		Query:    query,
		Count:    &total,
		Args:     args,
		Order:    "sort ASC, updated_at DESC",
	}) {
		response.FailJson(ctx, "查询失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "查询成功", struct {
		Total int64                     `json:"total"`
		Lists []models.ContentFieldType `json:"lists"`
	}{
		Total: total,
		Lists: lists,
	})
}

// Create 内容字段类型添加
func (c *ContentFieldTypeController) Create(ctx *gin.Context) {
	reqData := &models.ContentFieldType{
		Status:    1,
		IsDeleted: 0,
		CreatedAt: response.NowTime(),
		UpdatedAt: response.NowTime(),
	}
	rules := validator.NewRules(
		validator.NewRule("name", "类型名称", true, validator.TypeNoEmpty),
		validator.NewRule("icon", "类型图标", true, validator.TypeLink),
		validator.NewRule("description", "类型简介", false, validator.TypeNoEmpty),
		validator.NewRule("db_type", "数据库保存类型", true, validator.TypeNoEmpty),
		validator.NewRule("sort", "类型排序", true, validator.TypeNumber),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	repo := repository.New(&models.ContentFieldType{})

	// 检查同名
	hasSame := &models.ContentFieldType{}
	if repo.Find(hasSame, "is_deleted = 0 AND name = ?", reqData.Name) && hasSame.Id != 0 {
		response.FailJson(ctx, "已存在同名类型", nil)
		return
	}

	// 创建
	if !repo.Create(reqData) {
		response.FailJson(ctx, "添加失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "添加成功", nil)
}

// Update 内容字段类型编辑
func (c *ContentFieldTypeController) Update(ctx *gin.Context) {
	reqData := &models.ContentFieldType{}
	rules := validator.NewRules(
		validator.NewRule("id", "类型ID", true, validator.TypeNumberNoneZero),
		validator.NewRule("name", "类型名称", true, validator.TypeNoEmpty),
		validator.NewRule("icon", "类型图标", true, validator.TypeLink),
		validator.NewRule("description", "类型简介", false, validator.TypeNoEmpty),
		validator.NewRule("db_type", "数据库保存类型", true, validator.TypeNoEmpty),
		validator.NewRule("sort", "类型排序", true, validator.TypeNumber),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	repo := repository.New(&models.ContentFieldType{})

	// 检查类型状态
	hasType := &models.ContentFieldType{}
	if !repo.Find(hasType, "is_deleted = 0 AND id = ?", reqData.Id) || hasType.Id == 0 {
		response.FailJson(ctx, "类型信息已失效", nil)
		return
	}

	// 检查同名
	hasSame := &models.ContentFieldType{}
	if repo.Find(hasSame, "is_deleted = 0 AND name = ? AND id <> ?", reqData.Name, reqData.Id) && hasSame.Id != 0 {
		response.FailJson(ctx, "已存在同名类型", nil)
		return
	}

	// 更新字段
	refObj, err := reflects.NewObject(hasType)
	if err != nil {
		response.FailJson(ctx, "编辑失败, 请稍后再试", nil)
		return
	}
	fields := []string{"name", "icon", "description", "db_type", "sort"}
	refObj.BatchSetValueFromFields(fields, reqData)
	hasType.UpdatedAt = response.NowTime()

	// 创建
	if !repo.UpdateById(hasType.Id, hasType) {
		response.FailJson(ctx, "编辑失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "编辑成功", nil)
}

// Delete 内容字段类型删除
func (c *ContentFieldTypeController) Delete(ctx *gin.Context) {
	reqData := &models.ContentFieldType{}
	rules := validator.NewRules(
		validator.NewRule("id", "类型ID", true, validator.TypeNumberNoneZero),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	repo := repository.New(&models.ContentFieldType{})

	// 检查类型状态
	hasType := &models.ContentFieldType{}
	if !repo.Find(hasType, "is_deleted = 0 AND id = ?", reqData.Id) || hasType.Id == 0 {
		response.FailJson(ctx, "类型信息已失效", nil)
		return
	}

	if !repo.DeleteById(reqData.Id) {
		response.FailJson(ctx, "删除失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "删除成功", nil)
}

// Enable 内容字段类型启用
func (c *ContentFieldTypeController) Enable(ctx *gin.Context) {
	reqData := &models.ContentFieldType{}
	rules := validator.NewRules(
		validator.NewRule("id", "类型ID", true, validator.TypeNumberNoneZero),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	repo := repository.New(&models.ContentFieldType{})

	// 检查类型状态
	hasType := &models.ContentFieldType{}
	if !repo.Find(hasType, "is_deleted = 0 AND id = ? AND status = 0", reqData.Id) || hasType.Id == 0 {
		response.FailJson(ctx, "类型信息已失效", nil)
		return
	}

	if !repo.EnableById(reqData.Id) {
		response.FailJson(ctx, "操作失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "操作成功", nil)
}

// Disable 内容字段类型删除
func (c *ContentFieldTypeController) Disable(ctx *gin.Context) {
	reqData := &models.ContentFieldType{}
	rules := validator.NewRules(
		validator.NewRule("id", "类型ID", true, validator.TypeNumberNoneZero),
	)
	if !validator.ShouldBindFromPostForm(ctx, reqData, rules...) {
		return
	}

	repo := repository.New(&models.ContentFieldType{})

	// 检查类型状态
	hasType := &models.ContentFieldType{}
	if !repo.Find(hasType, "is_deleted = 0 AND id = ? AND status = 1", reqData.Id) || hasType.Id == 0 {
		response.FailJson(ctx, "类型信息已失效", nil)
		return
	}

	if !repo.DisableById(reqData.Id) {
		response.FailJson(ctx, "操作失败, 请稍后再试", nil)
		return
	}

	response.SuccessJson(ctx, "操作成功", nil)
}
